package cn.zhilianbao.ice.service;

import android.os.AsyncTask;

import com.bql.convenientlog.CLog;
import com.bql.utils.AsyncTaskUtils;
import com.bql.utils.CheckUtils;
import com.bql.utils.NetworkUtils;
import com.zhilianbao.leyaogo.app.LeYaoGoApplication;
import com.zhilianbao.leyaogo.utils.Utils;

import Glacier2.SessionCallback;
import Glacier2.SessionFactoryHelper;
import Glacier2.SessionHelper;
import Glacier2.SessionNotExistException;
import Ice.Current;
import Ice.LocalException;
import cn.zhilianbao.ice.callback.LeYaoChatCallback;
import cn.zhilianbao.ice.chat.Callback_ChatSession_setCallback;
import cn.zhilianbao.ice.chat.ChatCallbackPrx;
import cn.zhilianbao.ice.chat.ChatCallbackPrxHelper;
import cn.zhilianbao.ice.chat.ChatSessionPrx;
import cn.zhilianbao.ice.chat.ChatSessionPrxHelper;
import cn.zhilianbao.ice.chat.IMMessage;
import cn.zhilianbao.ice.chat.IMRegistryPrx;
import cn.zhilianbao.ice.chat.IMRegistryPrxHelper;
import cn.zhilianbao.ice.chat.IMServer;
import cn.zhilianbao.ice.chat.IMServerHolder;
import cn.zhilianbao.ice.chat.IMUser;
import cn.zhilianbao.ice.chat._ChatCallbackDisp;

/**
 * ClassName: IceService <br>
 * Description: ICE服务<br>
 * Author: Cyarie <br>
 * Created: 2016/11/11 09:24 <br>
 * Update Time：<br>
 * Update Description：<br>
 */
public class IceService {

    public static final String TAG = "ICEService";

    public static final String API_KEY = "1234567890";

    private Ice.Communicator communicator;//ICE 通信器

    private SessionHelper mSessionHelper;//会话帮助类

    private ChatSessionPrx mChatSessionPrx;//Chat 会话

    private boolean isInitializing;//是否正在初始化

    // The session factory and current session.
    private SessionFactoryHelper factory;

    private String host;

    /**
     * Chat回调接口
     */
    private LeYaoChatCallback mLeYaoChatCallback;


    //静态内部类，在加载该内部类时才会去创建单例对象 在static{}区块中初始化的数据 利用JVM的类加载机制 在很多情况下JVM已经为我们提供了同步控制
    private static class IceServiceHolder {
        public static IceService sInstance = new IceService();
    }


    /**
     * 注册Chat回调
     *
     * @param leYaoChatCallback
     */
    public void registerLeYaoChatCallback(LeYaoChatCallback leYaoChatCallback) {
        if (this.mLeYaoChatCallback != null)
            this.mLeYaoChatCallback = null;
        this.mLeYaoChatCallback = leYaoChatCallback;
    }


    private IceService() {

    }

    public static IceService getInstance() {
        return IceServiceHolder.sInstance;
    }

    /**
     * ICE服务初始化
     */
    public void initIce() {
        AsyncTaskUtils.exe(new AsyncTask<Void, Integer, Integer>() {
            Ice.InitializationData initData;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                CLog.i(TAG, "ICE init start");
                isInitializing = true;
            }

            @Override
            protected Integer doInBackground(Void... params) {

                try {
                    //ICE初始化数据
                    initData = new Ice.InitializationData();
                    //初始化properties
                    initData.properties = Ice.Util.createProperties();
                    //设置注册代理 192.168.1.241 7000
                    initData.properties.setProperty("Register.Proxy", "register:tcp -h 192.168.1.241 -p 7000");
                    //设置ACM Close
                    //                    initData.properties.setProperty("Ice.ACM.Close", "0");
                    //设置ACM Heartbeat
                    //                    initData.properties.setProperty("Ice.ACM.Heartbeat", "3");
                    //设置ACM Timeout
                    //                    initData.properties.setProperty("Ice.ACM.Timeout", "30");
                    //初始化通信器
                    communicator = Ice.Util.initialize(initData);
                    //注册代理
                    IMRegistryPrx server = IMRegistryPrxHelper.checkedCast(communicator.propertyToProxy("Register.Proxy"));
                    if (server != null) {
                        IMServer imServer = new IMServer();
                        int code = server.getServer(API_KEY, new IMServerHolder(imServer));
                        //success
                        if (code == 0) {
                            CLog.i(TAG, "HostName---" + imServer.getHostName());
                            CLog.i(TAG, "HostIP---" + imServer.getHostIP());
                            CLog.i(TAG, "Port---" + imServer.getPort());
                            if ((!CheckUtils.isEmpty(imServer.getHostName()) || !CheckUtils.isEmpty(imServer.getHostIP())) && imServer.getPort() != 0) {
                                StringBuilder builder = new StringBuilder();
                                builder.append("DemoGlacier2/router:tcp -p ");
                                if (imServer.getPort() != 0) {
                                    builder.append(imServer.getPort());
                                }
                                builder.append(" -h ");
                                if (!CheckUtils.isEmpty(imServer.getHostName())) {
                                    builder.append(imServer.getHostName());
                                    host = imServer.getHostName();
                                }
                                if (!CheckUtils.isEmpty(imServer.getHostIP())) {
                                    builder.append(imServer.getHostIP());
                                    host = imServer.getHostIP();
                                }
                                if (initData.properties != null) {
                                    initData.properties.setProperty("Ice.Default.Router", builder.toString());
                                }

                                //初始化通信器
                                //                                communicator = Ice.Util.initialize(initData);

                                //创建session factory
                                factory = new SessionFactoryHelper(initData, new SessionCallback() {
                                    @Override
                                    public void createdCommunicator(SessionHelper sessionHelper) {

                                    }

                                    @Override
                                    public void connected(SessionHelper sessionHelper) throws SessionNotExistException {
                                        // If the session has been reassigned avoid the spurious callback.
                                        if (sessionHelper != mSessionHelper)
                                            return;
                                        //                                        IChatCallback iChatCallback = new IChatCallback();
                                        ChatCallbackPrx callback = ChatCallbackPrxHelper.uncheckedCast(mSessionHelper.addWithUUID(new _ChatCallbackDisp() {
                                            @Override
                                            public void init(IMUser[] users, int groupUserCount, Current __current) {

                                            }

                                            @Override
                                            public void receiveMsg(IMMessage message, Current __current) {
                                                if (mLeYaoChatCallback != null)
                                                    mLeYaoChatCallback.receiverMsg(message);
                                            }

                                            @Override
                                            public void receiveCmd(int cmdType, int cmdSubType, String cmdJson, Current __current) {

                                            }
                                        }));
                                        mChatSessionPrx = ChatSessionPrxHelper.uncheckedCast(mSessionHelper.session());
                                        mChatSessionPrx.begin_setCallback(callback, new Callback_ChatSession_setCallback() {
                                            @Override

                                            public void response(int i) {
                                                CLog.i(TAG, "Connected with " + host);
                                            }

                                            @Override
                                            public void exception(LocalException e) {
                                                CLog.i(TAG, "exception " + e.toString());
                                                if (mSessionHelper != null) {
                                                    mSessionHelper.destroy();
                                                    //The session will be set to null on disconnected.
                                                }
                                            }
                                        });
                                    }

                                    @Override
                                    public void disconnected(SessionHelper sessionHelper) {
                                        // If the session has been reassigned avoid the spurious callback.
                                        if (sessionHelper != mSessionHelper)
                                            return;
                                        mSessionHelper = null;
                                        mChatSessionPrx = null;
                                        //失去连接 有网络的时候重连 没网络的时候 由网络广播重连
                                        if (NetworkUtils.isConnected(LeYaoGoApplication.getContext())) {
                                            initIce();
                                        }

                                        CLog.i(TAG, "disconnected");
                                    }

                                    @Override
                                    public void connectFailed(SessionHelper sessionHelper, Throwable throwable) {
                                        // If the session has been reassigned avoid the spurious callback.
                                        if (sessionHelper != mSessionHelper)
                                            return;
                                        CLog.i(TAG, throwable.getClass().getName());
                                    }
                                });
                                factory.setRouterIdentity(new Ice.Identity("router", "DemoGlacier2"));
                                factory.setRouterHost(host);
                                //通过userId tokenId创建会话
                                if (Utils.getUserLoginInfo() == null) {
                                    CLog.i(TAG, "user info can not be null");
                                    return 5;
                                }
                                String userId = Utils.getUserLoginInfo().getUserId() + "";
                                String tokenId = Utils.getUserLoginInfo().getTokenId();
                                // Connect to Glacier2 using SessionFactoryHelper
                                mSessionHelper = factory.connect(userId, tokenId);
                                return 0;
                                //                                if (communicator.getDefaultRouter() != null) {
                                //                                    //创建路由对象
                                //                                    final Ice.RouterPrx r = communicator.getDefaultRouter();
                                //                                    final Glacier2.RouterPrx router = Glacier2.RouterPrxHelper.checkedCast(r);
                                //                                    if (router == null) {
                                //                                        throw new NullPointerException("router is null");
                                //                                    }
                                //                                    //通过userId tokenId创建会话
                                //                                    if (Utils.getUserLoginInfo() == null) {
                                //                                        return 5;
                                //                                    }
                                //                                    String userId = Utils.getUserLoginInfo().getUserId() + "";
                                //                                    String tokenId = Utils.getUserLoginInfo().getTokenId();
                                //                                    Glacier2.SessionPrx session = router.createSession(userId, tokenId);
                                //                                    Ice.Identity callbackReceiverIdentity = new Ice.Identity("callbackReceiver", router.getCategoryForClient());
                                //                                    ObjectAdapter adapter = communicator.createObjectAdapterWithRouter("", router);
                                //                                    //激活
                                //                                    adapter.activate();
                                //                                    //客户端的回调，服务器那边有消息过来，会调用IChatCallback接口
                                //                                    ChatCallbackPrx callback = ChatCallbackPrxHelper.uncheckedCast
                                //                                            (adapter.add(new IChatCallback(), callbackReceiverIdentity));
                                //                                    mChatSessionPrx = ChatSessionPrxHelper.uncheckedCast(session);
                                //                                    mChatSessionPrx.setCallback(callback);
                                //                                    return 0;
                                //                                } else {
                                //                                    return 3;
                                //                                }
                            } else {
                                return 4;
                            }
                        }
                        //failed
                        else {
                            return code;
                        }
                    } else {
                        return 1;
                    }


                } catch (Exception e) {
                    CLog.e(TAG, e.toString());
                    return 2;
                }

            }

            @Override
            protected void onPostExecute(Integer integer) {
                super.onPostExecute(integer);
                isInitializing = false;
                if (integer == 0) {
                    CLog.i(TAG, integer + "---ICE init success");
                    //                    ThreadPool.schedule(() -> {
                    //                        CLog.i(TAG, "-----ICE session ping-----");
                    //                        if (mChatSessionPrx != null) {
                    //                            mChatSessionPrx.ice_ping();
                    //                        }
                    //                    }, 15, 15, TimeUnit.SECONDS);
                } else if (integer == 1) {
                    CLog.i(TAG, integer + "---failed--IMServer return null");
                } else if (integer == 2) {
                    CLog.i(TAG, integer + "---failed--occur Exception");
                } /*else if (integer == 3) {
                    CLog.i(TAG, integer + "---failed--communicator.getDefaultRouter() return null");
                } */ else if (integer == 4) {
                    CLog.i(TAG, integer + "---failed--register ICE return parameters HostName or HostIp or Port null");
                } else if (integer == 5) {
                    CLog.i(TAG, integer + "---failed--user login info return null");
                } else {
                    CLog.i(TAG, integer + "---failed--IMRegistryPrx.getServer");
                }
            }

        });
    }


    /**
     * 发送消息
     * <p>
     * return
     */
    public int sendMsg() {
        if (checkSessionExist()) {
            try {
                long time1 = System.currentTimeMillis();
                int flag = mChatSessionPrx.send(new IMMessage(0, 1162, (short) 2, 1069, (short) 1, "ICE聊天通信系统", System.currentTimeMillis()));
                long time = System.currentTimeMillis() - time1;
                CLog.i(TAG, "发送耗时=" + time + "ms");
                if (flag == 0) {
                    CLog.i(TAG, "消息发送成功");
                } else {
                    CLog.i(TAG, "消息发送失败");
                }
                return flag;
            } catch (Ice.ConnectionLostException e) {
                e.printStackTrace();
                mChatSessionPrx = null;
                initIce();
                CLog.i(TAG, e.toString());
            } catch (Ice.ConnectFailedException e) {
                e.printStackTrace();
                mChatSessionPrx = null;
                CLog.i(TAG, e.toString());
            } catch (Exception e) {
                e.printStackTrace();
                mChatSessionPrx = null;
                CLog.i(TAG, e.toString());
            }
        }
        return 1;
    }


    /**
     * 检测会话是否存在 不存在 则初始化会话
     *
     * @return
     */
    private boolean checkSessionExist() {
        if (mChatSessionPrx != null) {
            return true;
        } else {
            CLog.i(TAG, "---failed--ChatSessionPrx can not be null");
            if (!isInitializing) {
                initIce();
            }
            return false;
        }
    }

}
